#!/bin/bash
APP_BASE=$HOME

APP_LOG=$APP_BASE/logs
APP_RUN=$APP_BASE/run

# 当确实需要主动回收内存以解决内存碎片问题时,可以考虑在业务空闲期间调用System.gc()
# -XX:+PrintFlagsFinal
# 需要震荡堆时使用(默认) -XX:MinHeapFreeRatio=40 -XX:MaxHeapFreeRatio=70
# -XX:NewRatio(CMS GC无效)
# 代码中手动调用System.gc()不生效
# -XX:+DisableExplicitGC
#APP1_MEM_OPTS=" -Xmx800m -Xms800m -Xmn128m -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=80 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xss256k "
#APP2_MEM_OPTS="-Xmx1g -Xms1g -Xmn128m -XX:SurvivorRatio=2 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xss256k "
#APP3_MEM_OPTS="-Xmx2g -Xms2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -Xss256k "
COMMON_OPTS=""
# 已经默认设置 ‐XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled
CMS_OPTS="-XX:+UseConcMarkSweepGC -XX:ParallelGCThreads=4 -XX:ConcGCThreads=4 -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSScavengeBeforeRemark -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled"
#G1_OPTS=" -XX:+UseG1GC -XX:G1HeapRegionSize=1m -XX:MaxGCPauseMillis=200 -XX:TargetSurvivorRatio=50 -XX:InitiatingHeapOccupancyPercent=45 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=8 "
G1_OPTS="-XX:+UseG1GC"
# -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime
# PRINT_OPTS=" -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:-PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError "

DEBUG=false

clean_cache(){
    # 多个服务在一台机器上,暂不清理缓存
    echo "sync buffer to disk..."
    sync
    sleep 1
    echo "clean cache..."
    echo 3 > /proc/sys/vm/drop_caches
    sleep 1
}

init(){
  if [ ! -d $APP_LOG ]; then
    mkdir $APP_LOG
  fi
  if [ ! -d $APP_RUN ]; then
    mkdir $APP_RUN
  fi

  ## CMS_OPTS="$COMMON_OPTS $CMS_OPTS"
  CMS_OPTS="$COMMON_OPTS $G1_OPTS"
  G1_OPTS="$COMMON_OPTS $G1_OPTS"
  if $DEBUG ; then
    APP_OPTS="$G1_OPTS $APP_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="$APP_LOG/$APP_NAME".dump -Xlog:gc:"$APP_LOG/$APP_NAME".gc"
  else
    APP_OPTS="$G1_OPTS $APP_MEM_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="$APP_LOG/$APP_NAME".dump"
  fi

  APP_ROOT=$APP_BASE
  APP_BOOT=$APP_ROOT/$APP_NAME.jar
  APP_OUT=$APP_LOG/$APP_NAME.out
  APP_RUN_PID=$APP_RUN/$APP_NAME.pid
}

start(){
  cd $APP_LOG
  rm -rf $APP_NAME.out
  #rm -rf *.log

  echo "start project begin..." >> $APP_OUT
  cd $APP_ROOT
  # 通过maven设置manifest.mf中的lib路径,可以直接使用java -jar *.jar来启动应用并包含lib中的第三方jar
  echo "nohup java $APP_OPTS -Djava.security.egd=file:/dev/./urandom -jar $APP_BOOT > $APP_OUT 2>&1 &"
  # java $APP_OPTS -Djava.security.egd=file:/dev/./urandom -jar $APP_BOOT > $APP_OUT 2>&1
  nohup java $APP_OPTS -Djava.security.egd=file:/dev/./urandom -jar $APP_BOOT > $APP_OUT 2>&1 &
  echo $! > $APP_RUN_PID
  chmod 666 $APP_RUN_PID
  echo "start project end..." >> $APP_OUT
}

stop(){
  echo "stop project..." >> $APP_OUT
  if [ -f `$APP_RUN_PID` ]; then
    local TMP_PID=`cat $APP_RUN_PID`
    # 忽略错误继续执行
    set +e
    kill -9 `cat $APP_RUN_PID`
    sleep 5
    rm -rf $APP_RUN_PID
    echo "killed pid: $TMP_PID"
    unset TMP_PID
    # 恢复,不忽略错误
    set -e
  fi
  echo "stop project end..." >> $APP_OUT
}

restart(){
  stop
  sleep 1
  start
}

if [ $# -eq 0 ]; then
  echo "parameters must be not empty"
else
  if [ "$1" = "auth" ]; then
    APP_NAME="icloud-auth-boot"
    APP_MEM_OPTS="-Xmx1500m -Xms1500m"
  elif [ "$1" = "gateway" ]; then
    APP_NAME="icloud-gateway"
    APP_MEM_OPTS="-Xmx1500m -Xms1500m"

  elif [ "$1" = "system" ]; then
    APP_NAME="icloud-system-boot"
    APP_MEM_OPTS="-Xmx2g -Xms2g"

  elif [ "$1" = "article" ]; then
    APP_NAME="icloud-article-boot"
    APP_MEM_OPTS="-Xmx2g -Xms2g"

  elif [ "$1" = "wallet" ]; then
    APP_NAME="icloud-wallet-boot"
    APP_MEM_OPTS="-Xmx2g -Xms2g"

  else
    APP_NAME="icloud-system-boot"
    APP_MEM_OPTS="-Xmx2g -Xms2g"
  fi

  init
  restart
fi
